package com.zycfc.zsf.boot.mybatis.dynamicdatasource;

import org.springframework.jdbc.datasource.lookup.*;
import java.util.concurrent.atomic.*;
import javax.sql.*;
import java.util.*;
import org.springframework.transaction.support.*;
import org.slf4j.*;

public class MyAbstractRoutingDataSource extends AbstractRoutingDataSource
{
    private static final Logger log;
    private final int dataSourceNumber;
    private AtomicInteger count;
    private DataSource writeDataSource;
    private List<DataSource> queryDataSource;
    
    public MyAbstractRoutingDataSource(final int dataSourceNumber, final DataSource obj1, final List<DataSource> obj2) {
        this.count = new AtomicInteger(0);
        this.dataSourceNumber = dataSourceNumber;
        this.writeDataSource = obj1;
        this.queryDataSource = obj2;
    }
    
    public void afterPropertiesSet() {
        if (this.writeDataSource == null) {
            throw new IllegalArgumentException("Property 'writeDataSource' is required");
        }
        this.setDefaultTargetDataSource((Object)this.writeDataSource);
        final Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        targetDataSources.put(DataSourceType.write.getType(), this.writeDataSource);
        if (this.queryDataSource != null) {
            int i = 0;
            for (final DataSource d : this.queryDataSource) {
                targetDataSources.put(DataSourceType.read.getType() + i, d);
                ++i;
            }
        }
        this.setTargetDataSources((Map)targetDataSources);
        super.afterPropertiesSet();
    }
    
    protected Object determineCurrentLookupKey() {
        final boolean isCurrentTransactionReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
        if (!isCurrentTransactionReadOnly) {
            DataSourceContextHolder.write();
        }
        String key = DataSourceContextHolder.get();
        if (DataSourceType.write.getType().equals(key)) {
            key = DataSourceType.write.getType();
            return key;
        }
        final int number = this.getAndAdd();
        final int lookupKey = number % this.dataSourceNumber;
        key = DataSourceType.read.getType() + new Integer(lookupKey);
        return key;
    }
    
    private int getAndAdd() {
        if (this.count.intValue() >= Integer.MAX_VALUE) {
            this.count = new AtomicInteger(0);
        }
        return this.count.getAndAdd(1);
    }
    
    static {
        log = LoggerFactory.getLogger((Class)MyAbstractRoutingDataSource.class);
    }
}
